/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>

#include <pldm_over_mctp/pldm_over_mctp_emulex.h>

namespace test_pldm_over_mctp {

// ===== pldm_over_mctp_emulex tests =====

// Test FRU record ID mappings
TEST(pldm_over_mctp_emulex_constants_test, fru_record_id_constants) {
    EXPECT_EQ(FRU_RECORD_ID_GENERAL, 1);
    EXPECT_EQ(FRU_RECORD_ID_CHIP, 3);
    EXPECT_EQ(FRU_RECORD_ID_PORT0, 4);
    EXPECT_EQ(FRU_RECORD_ID_PORT1, 5);
}

// Test TLV type constants
TEST(pldm_over_mctp_emulex_constants_test, tlv_type_constants) {
    EXPECT_EQ(FW_VERSION_TLV_TYPE, 0x02);
    EXPECT_EQ(PART_NUMBER_TLV_TYPE, 0x03);
    EXPECT_EQ(SERIAL_NUMBER_TLV_TYPE, 0x04);
    EXPECT_EQ(WWNN_TLV_TYPE, 0x83);
    EXPECT_EQ(WWPN_TLV_TYPE, 0x84);
}

// Test FRU data structures
TEST(pldm_over_mctp_emulex_structures_test, fru_tlv_entry_structure) {
    dev::fru_tlv_entry_t entry;
    entry.type = FW_VERSION_TLV_TYPE;
    entry.length = 10;
    entry.value = "TEST_VALUE";

    EXPECT_EQ(entry.type, FW_VERSION_TLV_TYPE);
    EXPECT_EQ(entry.length, 10);
    EXPECT_EQ(entry.value, "TEST_VALUE");
}

TEST(pldm_over_mctp_emulex_structures_test, fru_record_info_structure) {
    dev::fru_record_info_t record;
    record.record_id = FRU_RECORD_ID_GENERAL;
    record.record_type = 1;
    record.number_field = 14;
    record.encoding_type = 1;

    dev::fru_tlv_entry_t tlv;
    tlv.type = PART_NUMBER_TLV_TYPE;
    tlv.length = 8;
    tlv.value = "12345678";

    record.tlv_entries.push_back(tlv);

    EXPECT_EQ(record.record_id, FRU_RECORD_ID_GENERAL);
    EXPECT_EQ(record.record_type, 1);
    EXPECT_EQ(record.number_field, 14);
    EXPECT_EQ(record.encoding_type, 1);
    EXPECT_EQ(record.tlv_entries.size(), 1);
    EXPECT_EQ(record.tlv_entries[0].type, PART_NUMBER_TLV_TYPE);
}

TEST(pldm_over_mctp_emulex_structures_test, emulex_fru_info_structure) {
    dev::emulex_fru_info_t fru_info;
    fru_info.firmware_version = "1.2.3";
    fru_info.part_number = "ABC123";
    fru_info.serial_number = "SN123456";
    fru_info.port0_wwnn = "WWNN0";
    fru_info.port1_wwnn = "WWNN1";
    fru_info.port0_wwpn = "WWPN0";
    fru_info.port1_wwpn = "WWPN1";

    EXPECT_EQ(fru_info.firmware_version, "1.2.3");
    EXPECT_EQ(fru_info.part_number, "ABC123");
    EXPECT_EQ(fru_info.serial_number, "SN123456");
    EXPECT_EQ(fru_info.port0_wwnn, "WWNN0");
    EXPECT_EQ(fru_info.port1_wwnn, "WWNN1");
    EXPECT_EQ(fru_info.port0_wwpn, "WWPN0");
    EXPECT_EQ(fru_info.port1_wwpn, "WWPN1");
}

// Test transfer flag constants
TEST(pldm_over_mctp_emulex_constants_test, transfer_flag_constants) {
    EXPECT_EQ(MCTP_PLDM_GET_RECORD_TABLE_FIRST_PART, 0x01);
    EXPECT_EQ(MCTP_PLDM_GET_RECORD_TABLE_NEXT_PART, 0x00);
    EXPECT_EQ(FRU_TABLE_TRANSFER_FLAG_END, 0x04);
    EXPECT_EQ(FRU_TABLE_TRANSFER_FLAG_START_END, 0x05);
}

// Test record TLV number mapping
TEST(pldm_over_mctp_emulex_constants_test, record_tlv_num_emulex_mapping) {
    EXPECT_EQ(dev::record_tlv_num_emulex.at(FRU_RECORD_ID_GENERAL), 14);
    EXPECT_EQ(dev::record_tlv_num_emulex.at(FRU_RECORD_ID_CHIP), 3);
    EXPECT_EQ(dev::record_tlv_num_emulex.at(FRU_RECORD_ID_PORT0), 8);
    EXPECT_EQ(dev::record_tlv_num_emulex.at(FRU_RECORD_ID_PORT1), 8);
}

// Test sensor data size validation
TEST(pldm_over_mctp_standard_validation_test, valid_sensor_data_sizes) {
    std::vector<uint8_t> valid_sizes = {0, 1, 2, 3, 4, 5};

    for (uint8_t size : valid_sizes) {
        // These sizes should be recognized as valid (no crash or exception)
        EXPECT_GE(size, 0);
        EXPECT_LE(size, 5);
    }
}

TEST(pldm_over_mctp_standard_validation_test, invalid_sensor_data_sizes) {
    std::vector<uint8_t> invalid_sizes = {6, 10, 99, 255};

    for (uint8_t size : invalid_sizes) {
        // These sizes should be considered invalid
        EXPECT_TRUE(size > 5 || size < 0);
    }
}

// Test composite sensor count validation
TEST(pldm_over_mctp_standard_validation_test, valid_composite_sensor_counts) {
    for (uint8_t count = 1; count <= 8; ++count) {
        // Valid range is 1-8
        EXPECT_GE(count, 1);
        EXPECT_LE(count, 8);
    }
}

TEST(pldm_over_mctp_standard_validation_test, invalid_composite_sensor_counts) {
    std::vector<uint8_t> invalid_counts = {0, 9, 10, 255};

    for (uint8_t count : invalid_counts) {
        // These counts should be considered invalid
        EXPECT_TRUE(count == 0 || count > 8);
    }
}

} // namespace test_pldm_over_mctp